home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / elm / elm2.4 / lib / opt_utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-01-19  |  10.5 KB  |  493 lines

  1.  
  2. static char rcsid[] = "@(#)$Id: opt_utils.c,v 5.7 1993/01/20 03:02:19 syd Exp $";
  3.  
  4. /*******************************************************************************
  5.  *  The Elm Mail System  -  $Revision: 5.7 $   $State: Exp $
  6.  *
  7.  *            Copyright (c) 1988-1992 USENET Community Trust
  8.  *            Copyright (c) 1986,1987 Dave Taylor
  9.  *******************************************************************************
  10.  * Bug reports, patches, comments, suggestions should be sent to:
  11.  *
  12.  *    Syd Weinstein, Elm Coordinator
  13.  *    elm@DSI.COM            dsinc!elm
  14.  *
  15.  *******************************************************************************
  16.  * $Log: opt_utils.c,v $
  17.  * Revision 5.7  1993/01/20  03:02:19  syd
  18.  * Move string declarations to defs.h
  19.  * From: Syd
  20.  *
  21.  * Revision 5.6  1993/01/19  05:07:05  syd
  22.  * Trim erroreous extra log entry
  23.  * From: Syd
  24.  *
  25.  * Revision 5.5  1993/01/19  04:47:12  syd
  26.  * Significant changes to provide consistent Date and From_ header
  27.  * cracking.  Overhauled date utilities and moved into library.  Moved
  28.  * real_from() into library.  Modified frm, newmail, and readmsg utilities
  29.  * to use library version of real_from().  Moved get_word() from Elm
  30.  * source into library.  Added new library routines atonum() and strfcpy().
  31.  * Fixed trailing backslash bug in len_next().
  32.  * From: chip@chinacat.unicom.com (Chip Rosenthal)
  33.  *
  34.  * Revision 5.4  1992/12/12  01:29:26  syd
  35.  * Fix double inclusion of sys/types.h
  36.  * From: Tom Moore <tmoore@wnas.DaytonOH.NCR.COM>
  37.  *
  38.  * Revision 5.3  1992/10/30  21:49:38  syd
  39.  * Add init of buf
  40.  * From: Syd via request from hessmann@unipas.fmi.uni-passau.de (Georg Hessmann)
  41.  *
  42.  * Revision 5.2  1992/10/24  13:06:23  syd
  43.  * make getdomainname optional
  44.  * From: Syd
  45.  *
  46.  * Revision 5.1  1992/10/03  22:41:36  syd
  47.  * Initial checkin as of 2.4 Release at PL0
  48.  *
  49.  *
  50.  ******************************************************************************/
  51.  
  52. /** This file contains routines that might be needed for the various
  53.      machines that the mailer can run on.  Please check the Makefile
  54.      for more help and/or information. 
  55.  
  56. **/
  57.  
  58. #include "headers.h"
  59. #include "s_error.h"
  60. #include <ctype.h>
  61.  
  62. #ifdef PWDINSYS
  63. #  include <sys/pwd.h>
  64. #else
  65. #  include <pwd.h>
  66. #endif
  67.  
  68. #ifdef BSD
  69. #undef tolower
  70. #undef toupper
  71. #endif
  72.  
  73. #ifndef GETHOSTNAME
  74. # ifdef DOUNAME
  75. #  include <sys/utsname.h>
  76. # endif
  77. #endif
  78.  
  79. #ifndef GETHOSTNAME
  80.  
  81. gethostname(cur_hostname,size) /* get name of current host */
  82. char *cur_hostname;
  83. int size;
  84. {
  85.     /** Return the name of the current host machine. **/
  86.  
  87. #if (defined(XENIX) || defined(M_UNIX)) & !defined(DOUNAME)
  88.     char    buf[32];
  89.     FILE    *fp;
  90.     char    *p;
  91.  
  92.     buf[0] = '\0';
  93.  
  94.     if ((fp = fopen("/etc/systemid", "r")) != 0) {
  95.       fgets(buf, sizeof(buf) - 1, fp);
  96.       fclose(fp);
  97.       if ((p = index(buf, '\n')) != NULL)
  98.         *p = '\0';
  99.       (void) strfcpy(cur_hostname, buf);
  100.       return 0;
  101.     }
  102.  
  103. #else   /* neither XENIX nor SCO UNIX */
  104.  
  105. #ifdef DOUNAME
  106.     /** This routine compliments of Scott McGregor at the HP
  107.         Corporate Computing Center **/
  108.      
  109.     int uname();
  110.     struct utsname name;
  111.  
  112.     (void) uname(&name);
  113.     (void) strfcpy(cur_hostname, name.nodename, size);
  114. #else
  115.     (void) strfcpy(cur_hostname, HOSTNAME, size-1);
  116. #endif    /* DOUNAME */
  117.  
  118.     return 0;
  119.  
  120. #endif  /* XENIX or SCO UNIX */
  121. }
  122.  
  123. #endif  /* GETHOSTNAME */
  124.  
  125.  
  126. gethostdomain(hostdom, size)    /* get domain of current host */
  127. char *hostdom;
  128. int size;
  129. {
  130.     char    buf[64];
  131.     FILE    *fp;
  132.     char    *p;
  133.  
  134.     if (size < 2)
  135.       return -1;
  136.  
  137.     buf[0] = '\0';
  138.  
  139.     if ((fp = fopen(hostdomfile, "r")) != 0) {
  140.       fgets(buf, sizeof(buf) - 1, fp);
  141.       fclose(fp);
  142.       if ((p = index(buf, '\n')) != NULL)
  143.         *p = '\0';
  144.     }
  145.     else {
  146. #ifdef USEGETDOMAINNAME
  147.       if (getdomainname(buf, sizeof(buf)) != 0)
  148. #endif
  149.         strfcpy(buf, DEFAULT_DOMAIN, sizeof(buf));
  150.     }
  151.     if (buf[0] != '\0' && buf[0] != '.') {
  152.       *hostdom++ = '.';
  153.       --size;
  154.     }
  155.     (void) strfcpy(hostdom, buf, size);
  156.  
  157.     return 0;
  158. }
  159.  
  160.  
  161. #ifndef HAS_CUSERID
  162.  
  163. char *cuserid(uname)
  164.      char *uname;
  165. {
  166.     /** Added for compatibility with Bell systems, this is the last-ditch
  167.         attempt to get the users login name, after getlogin() fails.  It
  168.         instantiates "uname" to the name of the user...(it also tries
  169.         to use "getlogin" again, just for luck)
  170.     **/
  171.     /** This wasn't really compatible.  According to our man page, 
  172.      ** It was inconsistent.  If the parameter is NULL then you return
  173.      ** the name in a static area.  Else the ptr is supposed to be a
  174.      ** pointer to l_cuserid bytes of memory [probally 9 bytes]...
  175.      ** It's not mention what it should return if you copy the name
  176.      ** into the array, so I chose NULL.
  177.      **                     Sept 20, 1988
  178.      **                    **WJL**
  179.      **/
  180.  
  181.   struct passwd *password_entry;
  182. #ifndef _POSIX_SOURCE
  183.   struct passwd *getpwuid();
  184. #endif
  185.   char   *name, *getlogin();
  186.   static char buf[10];
  187.   register returnonly = 0;
  188.   
  189.   if (uname == NULL) ++returnonly;
  190.   
  191.   if ((name = getlogin()) != NULL) {
  192.     if (returnonly) {
  193.       return(name);
  194.     } else {
  195.       strcpy(uname, name);
  196.       return name;
  197.     }
  198.   } 
  199.   else 
  200.     if (( password_entry = getpwuid(getuid())) != NULL) 
  201.       {
  202.     if (returnonly) 
  203.       {
  204.         return(password_entry->pw_name);
  205.       }
  206.     else 
  207.       {
  208.         strcpy(uname, password_entry->pw_name);
  209.         return name;
  210.       }
  211.       } 
  212.     else 
  213.       {
  214.     return NULL;
  215.       }
  216. }
  217.  
  218. #endif
  219.  
  220. #if defined(BSD) && !defined(_POSIX_SOURCE)
  221.  
  222. /** some supplementary string functions for Berkeley Unix systems **/
  223.  
  224. int
  225. tolower(ch)
  226. int ch;
  227. {
  228.     /** This should be a macro call, but if you use this as a macro
  229.         calls to 'tolower' where the argument is a function call will
  230.         cause the function to be called TWICE which is obviously the
  231.         wrong behaviour.  On the other hand, to just blindly translate
  232.         assuming the character is always uppercase can cause BIG
  233.         problems, so...
  234.     **/
  235.  
  236.     return ( isupper(ch) ? ch - 'A' + 'a' : ch );
  237. }
  238.  
  239. int
  240. toupper(ch)
  241. int ch;
  242. {
  243.     /** see comment for above routine - tolower() **/
  244.  
  245.     return ( islower(ch) ? ch - 'a' + 'A' : ch );
  246. }
  247.  
  248. #endif
  249.  
  250. #ifndef STRTOK
  251.  
  252. char *strtok(source, keys)
  253. char *source, *keys;
  254. {
  255.     /** This function returns a pointer to the next word in source
  256.         with the string considered broken up at the characters 
  257.         contained in 'keys'.  Source should be a character pointer
  258.         when this routine is first called, then NULL subsequently.
  259.         When strtok has exhausted the source string, it will 
  260.         return NULL as the next word. 
  261.  
  262.         WARNING: This routine will DESTROY the string pointed to
  263.         by 'source' when first invoked.  If you want to keep the
  264.         string, make a copy before using this routine!!
  265.      **/
  266.  
  267.     register int  last_ch;
  268.     static   char *sourceptr;
  269.          char *return_value;
  270.  
  271.     if (source != NULL)
  272.       sourceptr = source;
  273.     
  274.     if (*sourceptr == '\0') 
  275.       return(NULL);        /* we hit end-of-string last time!? */
  276.  
  277.     sourceptr += strspn(sourceptr, keys);    /* skip leading crap */
  278.     
  279.     if (*sourceptr == '\0') 
  280.       return(NULL);        /* we've hit end-of-string */
  281.  
  282.     last_ch = strcspn(sourceptr, keys);    /* end of good stuff */
  283.  
  284.     return_value = sourceptr;        /* and get the ret   */
  285.  
  286.     sourceptr += last_ch;            /* ...value          */
  287.  
  288.     if (*sourceptr != '\0')        /* don't forget if we're at END! */
  289.       sourceptr++;               /* and skipping for next time */
  290.  
  291.     return_value[last_ch] = '\0';        /* ..ending right    */
  292.     
  293.     return((char *) return_value);        /* and we're outta here! */
  294. }
  295.  
  296. #endif
  297.  
  298.  
  299. #ifndef STRPBRK
  300.  
  301. char *strpbrk(source, keys)
  302. char *source, *keys;
  303. {
  304.     /** Returns a pointer to the first character of source that is any
  305.         of the specified keys, or NULL if none of the keys are present
  306.         in the source string. 
  307.     **/
  308.  
  309.     register char *s, *k;
  310.  
  311.     for (s = source; *s != '\0'; s++) {
  312.       for (k = keys; *k; k++)
  313.         if (*k == *s)
  314.           return(s);
  315.     }
  316.     
  317.     return(NULL);
  318. }
  319.  
  320. #endif
  321.  
  322. #ifndef STRSPN
  323.  
  324. strspn(source, keys)
  325. char *source, *keys;
  326. {
  327.     /** This function returns the length of the substring of
  328.         'source' (starting at zero) that consists ENTIRELY of
  329.         characters from 'keys'.  This is used to skip over a
  330.         defined set of characters with parsing, usually. 
  331.     **/
  332.  
  333.     register int loc = 0, key_index = 0;
  334.  
  335.     while (source[loc] != '\0') {
  336.       key_index = 0;
  337.       while (keys[key_index] != source[loc])
  338.         if (keys[key_index++] == '\0')
  339.           return(loc);
  340.       loc++;
  341.     }
  342.  
  343.     return(loc);
  344. }
  345.  
  346. #endif
  347.  
  348. #ifndef STRCSPN
  349.  
  350. strcspn(source, keys)
  351. char *source, *keys;
  352. {
  353.     /** This function returns the length of the substring of
  354.         'source' (starting at zero) that consists entirely of
  355.         characters NOT from 'keys'.  This is used to skip to a
  356.         defined set of characters with parsing, usually. 
  357.         NOTE that this is the opposite of strspn() above
  358.     **/
  359.  
  360.     register int loc = 0, key_index = 0;
  361.  
  362.     while (source[loc] != '\0') {
  363.       key_index = 0;
  364.       while (keys[key_index] != '\0')
  365.         if (keys[key_index++] == source[loc])
  366.           return(loc);
  367.       loc++;
  368.     }
  369.  
  370.     return(loc);
  371. }
  372.  
  373. #endif
  374.  
  375. #ifndef TEMPNAM
  376. /* and a tempnam for temporary files */
  377. static int cnt = 0;
  378.  
  379. char *tempnam( dir, pfx)
  380.  char *dir, *pfx;
  381. {
  382.     char space[SLEN];
  383.     char *newspace;
  384.  
  385.     if (dir == NULL) {
  386.         dir = "/usr/tmp";
  387.     } else if (*dir == '\0') {
  388.         dir = "/usr/tmp";
  389.     }
  390.     
  391.     if (pfx == NULL) {
  392.         pfx = "";
  393.     }
  394.  
  395.     sprintf(space, "%s%s%d.%d", dir, pfx, getpid(), cnt);
  396.     cnt++;
  397.     
  398.     newspace = malloc(strlen(space) + 1);
  399.     if (newspace != NULL) {
  400.         strcpy(newspace, space);
  401.     }
  402.     return newspace;
  403. }
  404.  
  405. #endif
  406.  
  407. #ifndef GETOPT
  408.  
  409. /*LINTLIBRARY*/
  410. #define NULL    0
  411. #define EOF    (-1)
  412. #define ERR(s, c)    if(opterr){\
  413.     extern int strlen(), write();\
  414.     char errbuf[2];\
  415.     errbuf[0] = c; errbuf[1] = '\n';\
  416.     (void) write(2, argv[0], (unsigned)strlen(argv[0]));\
  417.     (void) write(2, s, (unsigned)strlen(s));\
  418.     (void) write(2, errbuf, 2);}
  419.  
  420. extern int strcmp();
  421.  
  422. int    opterr = 1;
  423. int    optind = 1;
  424. int    optopt;
  425. char    *optarg;
  426.  
  427. int
  428. getopt(argc, argv, opts)
  429. int    argc;
  430. char    **argv, *opts;
  431. {
  432.     static int sp = 1;
  433.     register int c;
  434.     register char *cp;
  435.  
  436.     if(sp == 1)
  437.         if(optind >= argc ||
  438.            argv[optind][0] != '-' || argv[optind][1] == '\0')
  439.             return(EOF);
  440.         else if(strcmp(argv[optind], "--") == NULL) {
  441.             optind++;
  442.             return(EOF);
  443.         }
  444.     optopt = c = argv[optind][sp];
  445.     if(c == ':' || (cp=index(opts, c)) == NULL) {
  446.         ERR(": illegal option -- ", c);
  447.         if(argv[optind][++sp] == '\0') {
  448.             optind++;
  449.             sp = 1;
  450.         }
  451.         return('?');
  452.     }
  453.     if(*++cp == ':') {
  454.         if(argv[optind][sp+1] != '\0')
  455.             optarg = &argv[optind++][sp+1];
  456.         else if(++optind >= argc) {
  457.             cp = catgets(elm_msg_cat, ErrorSet, ErrorGetoptReq,
  458.                 ": option requires an argument -- ");
  459.             ERR(cp, c);
  460.             sp = 1;
  461.             return('?');
  462.         } else
  463.             optarg = argv[optind++];
  464.         sp = 1;
  465.     } else {
  466.         if(argv[optind][++sp] == '\0') {
  467.             sp = 1;
  468.             optind++;
  469.         }
  470.         optarg = NULL;
  471.     }
  472.     return(c);
  473. }
  474.  
  475. #endif
  476.  
  477. #ifndef RENAME
  478. int rename(tmpfname, fname)
  479. #ifdef ANSI_C
  480. const
  481. #endif
  482.    char *tmpfname, *fname;
  483. {
  484.     int status;
  485.  
  486.     (void) unlink(fname);
  487.     if ((status = link(tmpfname, fname)) != 0)
  488.         return(status);
  489.     (void) unlink(tmpfname);
  490.     return(0);
  491. }
  492. #endif
  493.